package com.example.payment.service.impl;

import com.example.payment.dto.PaymentRequest;
import com.example.payment.dto.PaymentResponse;
import com.example.payment.entity.PaymentOrder;
import com.example.payment.entity.PaymentRecord;
import com.example.payment.enums.PaymentStatus;
import com.example.payment.enums.PaymentChannel;
import com.example.payment.repository.PaymentOrderRepository;
import com.example.payment.repository.PaymentRecordRepository;
import com.example.payment.service.PaymentService;
import com.example.payment.service.PaymentStrategy;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
@Transactional
public class PaymentServiceImpl implements PaymentService {
    
    private static final Logger log = LoggerFactory.getLogger(PaymentServiceImpl.class);
    
    @Autowired
    private PaymentOrderRepository paymentOrderRepository;
    
    @Autowired
    private PaymentRecordRepository paymentRecordRepository;
    
    @Autowired
    private Map<String, PaymentStrategy> paymentStrategies;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @Override
    public PaymentResponse createPayment(PaymentRequest request) {
        try {
            log.info("创建支付订单: {}", request);
            
            // 检查是否已存在相同业务订单
            Optional<PaymentOrder> existingOrder = paymentOrderRepository.findByBusinessOrderNo(request.getBusinessOrderNo());
            if (existingOrder.isPresent()) {
                PaymentOrder order = existingOrder.get();
                if (PaymentStatus.SUCCESS.equals(order.getStatus())) {
                    return PaymentResponse.builder()
                        .success(false)
                        .errorCode("ORDER_ALREADY_PAID")
                        .errorMessage("订单已支付")
                        .build();
                }
                if (PaymentStatus.PENDING.equals(order.getStatus()) && order.getExpiredAt().isAfter(LocalDateTime.now())) {
                    return PaymentResponse.builder()
                        .orderNo(order.getOrderNo())
                        .businessOrderNo(order.getBusinessOrderNo())
                        .status(order.getStatus())
                        .success(true)
                        .message("订单已存在，请继续支付")
                        .build();
                }
            }
            
            // 创建支付订单
            PaymentOrder order = new PaymentOrder();
            order.setBusinessOrderNo(request.getBusinessOrderNo());
            order.setBusinessType(request.getBusinessType());
            order.setAmount(request.getAmount());
            order.setCurrency(request.getCurrency());
            order.setDescription(request.getDescription());
            order.setPaymentType(request.getPaymentType());
            order.setChannel(request.getChannel());
            order.setReturnUrl(request.getReturnUrl());
            order.setNotifyUrl(request.getNotifyUrl());
            order.setUserId(request.getUserId());
            order.setUserName(request.getUserName());
            order.setStatus(PaymentStatus.PENDING);
            
            order = paymentOrderRepository.save(order);
            
            // 调用对应的支付策略
            PaymentStrategy strategy = getPaymentStrategy(request.getChannel());
            if (strategy == null) {
                throw new RuntimeException("不支持的支付渠道: " + request.getChannel());
            }
            
            PaymentResponse response = strategy.createPayment(request);
            response.setOrderNo(order.getOrderNo());
            response.setBusinessOrderNo(order.getBusinessOrderNo());
            
            // 记录支付记录
            savePaymentRecord(order, "CREATE", response.isSuccess() ? "SUCCESS" : "FAILED", 
                objectMapper.writeValueAsString(request), objectMapper.writeValueAsString(response));
            
            return response;
            
        } catch (Exception e) {
            log.error("创建支付订单失败", e);
            return PaymentResponse.builder()
                .success(false)
                .errorCode("CREATE_PAYMENT_FAILED")
                .errorMessage("创建支付订单失败: " + e.getMessage())
                .build();
        }
    }
    
    @Override
    public PaymentResponse queryPaymentStatus(String orderNo) {
        try {
            Optional<PaymentOrder> orderOpt = paymentOrderRepository.findByOrderNo(orderNo);
            if (!orderOpt.isPresent()) {
                return PaymentResponse.builder()
                    .success(false)
                    .errorCode("ORDER_NOT_FOUND")
                    .errorMessage("订单不存在")
                    .build();
            }
            
            PaymentOrder order = orderOpt.get();
            
            // 如果订单已过期，更新状态
            if (PaymentStatus.PENDING.equals(order.getStatus()) && order.getExpiredAt().isBefore(LocalDateTime.now())) {
                order.setStatus(PaymentStatus.EXPIRED);
                paymentOrderRepository.save(order);
            }
            
            return PaymentResponse.builder()
                .orderNo(order.getOrderNo())
                .businessOrderNo(order.getBusinessOrderNo())
                .status(order.getStatus())
                .success(true)
                .message("查询成功")
                .build();
                
        } catch (Exception e) {
            log.error("查询支付状态失败", e);
            return PaymentResponse.builder()
                .success(false)
                .errorCode("QUERY_FAILED")
                .errorMessage("查询失败: " + e.getMessage())
                .build();
        }
    }
    
    @Override
    public boolean handleCallback(Map<String, String> callbackData) {
        try {
            String orderNo = callbackData.get("orderNo");
            if (orderNo == null) {
                log.error("回调数据缺少订单号");
                return false;
            }
            
            Optional<PaymentOrder> orderOpt = paymentOrderRepository.findByOrderNo(orderNo);
            if (!orderOpt.isPresent()) {
                log.error("订单不存在: {}", orderNo);
                return false;
            }
            
            PaymentOrder order = orderOpt.get();
            PaymentStrategy strategy = getPaymentStrategy(order.getChannel());
            if (strategy == null) {
                log.error("不支持的支付渠道: {}", order.getChannel());
                return false;
            }
            
            boolean success = strategy.handleCallback(callbackData);
            
            // 记录回调记录
            savePaymentRecord(order, "CALLBACK", success ? "SUCCESS" : "FAILED", 
                objectMapper.writeValueAsString(callbackData), "");
            
            return success;
            
        } catch (Exception e) {
            log.error("处理支付回调失败", e);
            return false;
        }
    }
    
    @Override
    public List<PaymentOrder> getUserOrders(Long userId) {
        return paymentOrderRepository.findByUserId(userId);
    }
    
    @Override
    public List<PaymentOrder> getUserOrdersByStatus(Long userId, PaymentStatus status) {
        return paymentOrderRepository.findByUserIdAndStatus(userId, status);
    }
    
    @Override
    public void processExpiredOrders() {
        List<PaymentOrder> expiredOrders = paymentOrderRepository.findExpiredOrders(PaymentStatus.PENDING, LocalDateTime.now());
        for (PaymentOrder order : expiredOrders) {
            order.setStatus(PaymentStatus.EXPIRED);
            paymentOrderRepository.save(order);
            log.info("订单已过期: {}", order.getOrderNo());
        }
    }
    
    private PaymentStrategy getPaymentStrategy(PaymentChannel channel) {
        String strategyName = channel.name().toLowerCase() + "PaymentStrategy";
        return paymentStrategies.get(strategyName);
    }
    
    private void savePaymentRecord(PaymentOrder order, String action, String result, String requestData, String responseData) {
        try {
            PaymentRecord record = new PaymentRecord();
            record.setOrderNo(order.getOrderNo());
            record.setStatus(PaymentStatus.valueOf(result));
            record.setChannel(order.getChannel());
            record.setAmount(order.getAmount());
            record.setRequestData(requestData);
            record.setResponseData(responseData);
            record.setProcessedAt(LocalDateTime.now());
            
            paymentRecordRepository.save(record);
        } catch (Exception e) {
            log.error("保存支付记录失败", e);
        }
    }
} 